package redux;

import com.intellij.ide.IdeView;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
import com.intellij.openapi.ide.CopyPasteManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDirectory;

import java.awt.datatransfer.StringSelection;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * Created by gaoshuai09
 */
public class ReduxCreateAction extends AnAction {
    public static final String REDUCER_FILE = "%s/src/biz/common/redux/Reducers.ts";
    public static final String NAVIGATOR_FILE = "%s/src/global/navigator/RootNavigator.ts";

    MyDialog myDialog;
    private Project mProject;
    private String mAuthor;
    private String mFunctionName;
    private String mCursorPath;
    private String mCmptName;

    private enum CodeType {
        Page, Action, Reducer
    }

    @Override
    public void actionPerformed(AnActionEvent e) {
        init(e);
        refreshProject(e);
    }

    /**
     * 获取当前光标选中的文件,如果没选中文件,返回App路径
     *
     * @return
     */
    private String getSelectedDir(AnActionEvent e) {
        if (e == null) return null;
        final DataContext dataContext = e.getDataContext();
        final IdeView view = LangDataKeys.IDE_VIEW.getData(dataContext);
        if (view == null) {
            return null;
        }
        final PsiDirectory dir = view.getOrChooseDirectory(); // 拿到当前选择的文件夹，也就是右键点击的文件夹
        if (dir == null) {
            return null;
        }
        String dirStr = dir.getVirtualFile().getPath() + "/";
        return dirStr;
    }


    /**
     * 刷新项目
     *
     * @param e
     */
    private void refreshProject(AnActionEvent e) {
        e.getProject().getBaseDir().refresh(false, true);
    }


    /**
     * 初始化Dialog
     */

    private void init(AnActionEvent e) {
        mProject = e.getData(PlatformDataKeys.PROJECT);
        mCursorPath = getSelectedDir(e);
        if (mProject == null || mCursorPath == null) {
            Messages.showErrorDialog("请在项目的源码文件夹中创建Redux代码", "退出");
            return;
        }
        myDialog = new MyDialog((author, moduleName, cmptName) -> {
            if (author == null || author.isEmpty()) {
                Messages.showErrorDialog("RD信息不能为空", "重试");
                return;
            }
            if (moduleName == null || moduleName.isEmpty()) {
                Messages.showErrorDialog("功能模块信息不能为空", "重试");
                return;
            }
            int result = Messages.showYesNoDialog("将在 [" + mCursorPath + "] 下创建Redux文件", "注意", null);
            if (result == Messages.YES) {
                mAuthor = author;
                mFunctionName = upperCase(moduleName);
                mCmptName = cmptName;
                createClassFiles();
                myDialog.dispose();
                result = Messages.showYesNoDialog("创建成功,是否复制相关内容,并打开Reducer和RootNavigator?", "提示", null);
                if (result == Messages.YES) {
                    openFileInEditor(NAVIGATOR_FILE);
                    openFileInEditor(REDUCER_FILE);
                    CopyPasteManager copyPasteManager = CopyPasteManager.getInstance();
                    copyPasteManager.setContents(new StringSelection(String.format("%sReducer:%sReducer", mFunctionName, mFunctionName)));
                }
            }
        });
        myDialog.setVisible(true);
    }

    public String upperCase(String str) {
        return str.substring(0, 1).toUpperCase() + str.substring(1);
    }

    private void openFileInEditor(String path) {
        VirtualFile virtualFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(new File(String.format(path, mProject.getBasePath())));
        virtualFile.refresh(false, true);
        new OpenFileDescriptor(mProject, virtualFile).navigate(true);
    }

    /**
     * 生成类文件
     */
    private void createClassFiles() {
        createClassFile(CodeType.Page);
        createClassFile(CodeType.Action);
        createClassFile(CodeType.Reducer);
    }


    /**
     * 生成Redux框架代码
     *
     * @param codeType
     */
    private void createClassFile(CodeType codeType) {
        String fileName = "";
        String content = "";
        String appPath = mCursorPath;
        switch (codeType) {
            case Page:
                fileName = "$FunNamePage.tsx";
                content = ReadTemplateFile(fileName);
                content = dealTemplateContent(content);
                writeToFile(content, appPath + mFunctionName.toLowerCase(), mFunctionName + mCmptName + ".tsx");
                break;
            case Action:
                fileName = "$FunNameAction.ts";
                content = ReadTemplateFile(fileName);
                content = dealTemplateContent(content);
                writeToFile(content, appPath + mFunctionName.toLowerCase(), mFunctionName + "Action.ts");
                break;
            case Reducer:
                fileName = "$FunNameReducer.ts";
                content = ReadTemplateFile(fileName);
                content = dealTemplateContent(content);
                writeToFile(content, appPath + mFunctionName.toLowerCase(), mFunctionName + "Reducer.ts");
                break;
        }
    }


    /**
     * 替换模板中字符
     *
     * @param content
     * @return
     */
    private String dealTemplateContent(String content) {
        content = content.replace("$FunNamePage", mFunctionName + mCmptName);
        content = content.replace("$FunName", mFunctionName);
        content = content.replace("$funName", mFunctionName.toLowerCase());
        content = content.replace("$author", mAuthor);
        content = content.replace("$date", getDate());
        return content;
    }

    /**
     * 获取当前时间
     *
     * @return
     */
    public String getDate() {
        Date currentTime = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd");
        String dateString = formatter.format(currentTime);
        return dateString;
    }


    /**
     * 读取模板文件中的字符内容
     *
     * @param fileName 模板文件名
     * @return
     */
    private String ReadTemplateFile(String fileName) {
        InputStream in = null;
        in = this.getClass().getResourceAsStream("/redux/Template/" + fileName);
        String content = "";
        try {
            content = new String(readStream(in));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return content;
    }


    private byte[] readStream(InputStream inputStream) throws IOException {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len = -1;
        try {
            while ((len = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            outputStream.close();
            inputStream.close();
        }

        return outputStream.toByteArray();
    }


    /**
     * 生成
     *
     * @param content   类中的内容
     * @param classPath 类文件路径
     * @param className 类文件名称
     */
    private void writeToFile(String content, String classPath, String className) {
        try {
            File floder = new File(classPath);
            if (!floder.exists()) {
                floder.mkdirs();
            }

            File file = new File(classPath + "/" + className);
            if (!file.exists()) {
                file.createNewFile();
            }

            FileWriter fw = new FileWriter(file.getAbsoluteFile());
            BufferedWriter bw = new BufferedWriter(fw);
            bw.write(content);
            bw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public static void main(String... args) {
    }
}
